package com.party.mobile.biz.crowdfund;

import com.google.common.base.Strings;
import com.google.common.collect.Maps;
import com.party.common.constant.Constant;
import com.party.common.utils.BigDecimalUtils;
import com.party.common.utils.DateUtils;
import com.party.common.utils.PartyCode;
import com.party.common.utils.StringUtils;
import com.party.core.exception.BusinessException;
import com.party.core.model.BaseModel;
import com.party.core.model.YesNoStatus;
import com.party.core.model.activity.ActStatus;
import com.party.core.model.activity.Activity;
import com.party.core.model.activity.ActivityDetail;
import com.party.core.model.activity.CrowfundResources;
import com.party.core.model.audio.Audio;
import com.party.core.model.counterfoil.Counterfoil;
import com.party.core.model.counterfoil.CounterfoilBusiness;
import com.party.core.model.crowdfund.*;
import com.party.core.model.distributor.DistributorDetail;
import com.party.core.model.distributor.DistributorDetailType;
import com.party.core.model.distributor.DistributorRelation;
import com.party.core.model.distributor.DistributorRelationType;
import com.party.core.model.member.*;
import com.party.core.model.message.IdentityType;
import com.party.core.model.order.*;
import com.party.core.model.wechatPlatform.WechatOpenMember;
import com.party.core.service.activity.IActivityDetailService;
import com.party.core.service.activity.IActivityService;
import com.party.core.service.activity.ICrowfundResourcesService;
import com.party.core.service.audio.IAudioService;
import com.party.core.service.counterfoil.ICounterfoilBusinessService;
import com.party.core.service.counterfoil.ICounterfoilService;
import com.party.core.service.crowdfund.*;
import com.party.core.service.crowdfund.biz.ProjectDetailCountBizService;
import com.party.core.service.distributor.IDistributorDetailService;
import com.party.core.service.distributor.IDistributorRelationService;
import com.party.core.service.member.*;
import com.party.core.service.member.biz.MemberPersonalCountBizService;
import com.party.core.service.member.util.MemberFormUtil;
import com.party.core.service.order.IOrderFormService;
import com.party.core.service.order.IOrderFormSubInfoService;
import com.party.core.service.system.ISysConfigService;
import com.party.core.service.wechat.IWechatMerchantsService;
import com.party.core.service.wechatPlatform.IWechatOpenMemberService;
import com.party.mobile.biz.analyze.MemberCopartnerDetailBizService;
import com.party.mobile.biz.analyze.MemberMerchantDetailBizService;
import com.party.mobile.biz.distributor.DistributorBizService;
import com.party.mobile.biz.file.FileBizService;
import com.party.mobile.biz.order.OrderBizService;
import com.party.mobile.web.dto.crowdfund.input.ApplyInput;
import com.party.mobile.web.dto.crowdfund.input.StatisticsInput;
import com.party.mobile.web.dto.crowdfund.output.ActivityDetailOutput;
import com.party.mobile.web.dto.crowdfund.output.TabDataOutput;
import com.party.mobile.web.dto.distributor.input.ApplyDistributorInput;
import com.party.mobile.web.dto.login.output.CurrentUser;
import com.party.mobile.web.dto.order.Output.OrderOutput;
import com.party.mobile.web.dto.order.input.BookOrderInput;
import com.party.notify.notifyPush.officialPartner.ICopartnerNotifySendService;
import com.party.notify.notifyPush.officialPartner.IOfficialPartnerNotifySendService;
import com.party.notify.notifyPush.servce.INotifySendService;
import com.party.pay.model.query.TradeStatus;
import com.party.synthesis.IProjectMessageService;
import org.apache.commons.lang3.StringEscapeUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.List;
import java.util.Map;

/**
 * 众筹活动业务接口
 * Created by wei.li
 *
 * @date 2017/2/24 0024
 * @time 17:57
 */

@Service
public class CrowdfundActivityBizService {

    @Autowired
    private IActivityService activityService;

    @Autowired
    private IMemberService memberService;

    @Autowired
    private IActivityDetailService activityDetailService;

    @Autowired
    private OrderBizService orderBizService;

    @Autowired
    private IMemberActService memberActService;

    @Autowired
    private IOrderFormService orderFormService;

    @Autowired
    private ProjectBizService projectBizService;

    @Autowired
    private ITargetProjectService targetProjectService;

    @Autowired
    private IProjectService projectService;

    @Autowired
    private ICrowfundResourcesService crowfundResourcesService;

    @Autowired
    private DistributorBizService distributorBizService;

    @Autowired
    private IDistributorRelationService distributorRelationService;

    @Autowired
    private IDistributorDetailService distributorDetailService;

    @Autowired
    private INotifySendService notifySendService;

    @Autowired
    private IOfficialPartnerNotifySendService officialPartnerNotifySendService;
    @Autowired
    private ICopartnerNotifySendService copartnerNotifySendService;

    @Autowired
    private IMemberMerchantService memberMerchantService;

    @Autowired
    private IPartnerMemberService partnerMemberService;

    @Autowired
    private FileBizService fileBizService;

    @Autowired
    private MemberMerchantDetailBizService memberMerchantDetailBizService;

    @Autowired
    private MemberCopartnerDetailBizService memberCopartnerDetailBizService;

    @Autowired
    private IMemberExternalAppService memberExternalAppService;

    @Autowired
    private IWechatMerchantsService wechatMerchantsService;

    @Autowired
    private IWechatOpenMemberService wechatOpenMemberService;

    @Autowired
    private MemberPersonalCountBizService memberPersonalCountBizService;

    @Autowired
    private ProjectDetailCountBizService projectDetailCountBizService;

    @Autowired
    private ISysConfigService sysConfigService;

    @Autowired
    private IAudioService audioService;

    @Autowired
    private IProjectGradationService projectGradationService;

    @Autowired
    private IEventGradationService eventGradationService;

    @Autowired
    private ICrowdfundEventService crowdfundEventService;

    @Autowired
    private IProjectInfoGradationService projectInfoGradationService;

    @Autowired
    private IProjectMessageService projectMessageService;

    @Autowired
    private ICounterfoilService counterfoilService;

    @Autowired
    private ICounterfoilBusinessService counterfoilBusinessService;

    @Autowired
    private IOrderFormSubInfoService orderFormSubInfoService;

    @Autowired
    private IMemberGroupService memberGroupService;

    // 默认公众号名称
    @Value("#{wechat['wechat.wwz.appname']}")
    private String appName;
    // 默认公众号头像链接
    @Value("#{wechat['wechat.wwz.headimgurl']}")
    private String headImgUrl;
    // 默认公众号二维码链接
    @Value("#{wechat['wechat.wwz.qrurl']}")
    private String qrUrl;

    protected static Logger logger = LoggerFactory.getLogger(CrowdfundActivityBizService.class);

    /**
     * 获取活动详情
     *
     * @param id          编号
     * @param currentUser 当前用户
     * @return 活动详情
     */
    public ActivityDetailOutput detail(String id, CurrentUser currentUser, Integer type) {
        Activity activity = activityService.get(id);/**/
        if (null == activity || activity.getDelFlag().equals("1")) {
            throw new BusinessException(PartyCode.IS_NO_DATA, "该众筹项目不存在");
        }
        ActivityDetailOutput activityDetailOutput = ActivityDetailOutput.transform(activity);

        int joinNum = orderFormService.calculateBuyNum(activity.getId(), null, false, OrderType.ORDER_ACTIVITY.getCode());

        // 报名人数带退款
        Integer crowdfundNum = projectService.countByActivity(activity.getId(), null);
        activityDetailOutput.setJoinNum(crowdfundNum);
        activityDetailOutput.setProjectJoinNum(joinNum);

        //是否已经到期
        Integer result = DateUtils.compareDate(new Date(), activity.getEndTime());
        if (result == 1) {
            activityDetailOutput.setClosed(true);
        }

        //创建者
        MemberGroup member = memberGroupService.get(activity.getMember());
        if (!Strings.isNullOrEmpty(activity.getPublisher()) && !Strings.isNullOrEmpty(activity.getPublisher())) {
            activityDetailOutput.setAuthorName(activity.getPublisher());
            activityDetailOutput.setAuthorLogo(activity.getPublisherLogo());
        } else {
            activityDetailOutput.setAuthorName(member.getRealname());
            activityDetailOutput.setAuthorLogo(member.getLogo());
        }
        activityDetailOutput.setAuthorId(activity.getMember());
        activityDetailOutput.setTemplateStyle(activity.getTemplateStyle());

        //详情
        ActivityDetail activityDetail = activityDetailService.getByRefId(activity.getId());
        if (null != activityDetail) {
            activityDetailOutput.setContent(StringEscapeUtils.unescapeHtml4(activityDetail.getContent()));
            activityDetailOutput.setMatchStandard(StringEscapeUtils.unescapeHtml4(activityDetail.getMatchStandard()));
            activityDetailOutput.setApplyRelated(StringEscapeUtils.unescapeHtml4(activityDetail.getApplyRelated()));
        }

        // 跑马灯
        List<CrowfundResources> picList = crowfundResourcesService.findByRefId(activity.getId(), "1");
        activityDetailOutput.setPicList(picList);

        // 视频
        List<CrowfundResources> videoList = crowfundResourcesService.findByRefId(activity.getId(), "2");
        if (videoList.size() > 0) {
            activityDetailOutput.setVideo(videoList.get(0));
        }

        if (null != currentUser) {
            //是否报名过
            MemberAct memberAct = memberActService.findByMemberAct(currentUser.getId(), id);
            if (memberAct != null) {
                TargetProject targetProject = targetProjectService.findByOrderId(memberAct.getOrderId());
                Project project = projectService.get(targetProject.getProjectId());
                activityDetailOutput.setMyProjectId(project.getId());
            }

            if (null == type) {
                type = DistributorRelationType.CROWDFUND_REPRESENT.getCode();
            }

            //是否已经众筹
            DistributorRelation distributorRelation
                    = distributorRelationService.get(type, id, currentUser.getId());
            if (null != distributorRelation) {
                activityDetailOutput.setParentId(distributorRelation.getParentId());
                activityDetailOutput.setDistributorId(distributorRelation.getDistributorId());
            }
        } else {
            logger.error("没有获取到登录用户；项目id--{}", id);
        }

        //如果没有绑定事件
        if (!Strings.isNullOrEmpty(activity.getEventId())) {
            Activity count = activityService.countForEventId(activity.getEventId());

            //报名人数带退款
            Integer allJoinNum = projectService.countByEvent(activity.getEventId(), null);
            activityDetailOutput.setJoinNum(allJoinNum);
            activityDetailOutput.setFavorerNum(count.getFavorerNum());
            activityDetailOutput.setBeCrowdfundNum(count.getBeCrowdfundNum());
            activityDetailOutput.setCrowdfundedNum(count.getCrowdfundedNum());
        }

        MemberGroup newPartner = memberGroupService.getPartner(activity.getMember());
        //公众号信息
        //MemberMerchant memberMerchant = memberMerchantService.findByMemberId(activity.getMember());
        if (newPartner != null && newPartner.getOpenStatus().equals(YesNoStatus.YES.getCode())) {
            if (YesNoStatus.YES.getCode().equals(newPartner.getMandatoryAttention())) {
                MemberExternalApp memberExternalApp
                        = memberExternalAppService.findByMemberIdAndDeployType(newPartner.getId(),
                        newPartner.getDeployType());
                WechatOpenMember wechatOpenMember = wechatOpenMemberService.get(memberExternalApp.getExternalAccountId());
                activityDetailOutput.setQrUrl(wechatOpenMember.getQrcodeUrl());
                activityDetailOutput.setHeadImg(wechatOpenMember.getHeadImg());
                activityDetailOutput.setAppName(wechatOpenMember.getNickName());
            }
        } else {
            activityDetailOutput.setQrUrl(qrUrl);
            activityDetailOutput.setHeadImg(headImgUrl);
            activityDetailOutput.setAppName(appName);
        }

        //是否播放音乐(0否/是)
        Integer isPlayMusic = 0;
        //音频url
        String audioUrl = "";
        try {
            Audio audio = audioService.findAudioByEventId(activity.getEventId());
            if (null != audio) {
                isPlayMusic = 1;
                audioUrl = audio.getAudioUrl();
            }
        } catch (Exception e) {
            logger.info("众筹项目详情页H5,音频获取失败", e.getMessage());
        }
        activityDetailOutput.setIsPlayMusic(isPlayMusic);
        activityDetailOutput.setAudioUrl(audioUrl);

        return activityDetailOutput;
    }

    /**
     * 活动报名
     *
     * @param applyInput 输入视图
     * @param memberId   会员编号
     * @param payType    付款类型
     * @return 报名信息
     */
    @Transactional
    public Map<String, Object> apply(ApplyInput applyInput, String memberId, Integer payType, Counterfoil counterfoil) {
        Map<String, Object> map = Maps.newHashMap();
        MemberAct dbMemberAct = memberActService.findByMemberAct(memberId, applyInput.getId());
        Activity activity = activityService.get(applyInput.getId()); // 对应活动
        MemberAct memberAct;

        if (sysConfigService.isOpenExpirationRestriction()) {
            boolean isExpire = MemberFormUtil.isExpire(activity.getMember(), null);
            if (isExpire) {
                throw new BusinessException("该商户歇业中，无法报名");
            }
        }

        map.put("isApply",false);
        //修改报名
        if (null != dbMemberAct) {
            map.put("isApply",true);
            // 已经报名,取出报名信息
            logger.info("已经存在报名信息：" + dbMemberAct.toString());
            if (ActStatus.ACT_STATUS_AUDITING.getCode().equals(dbMemberAct.getCheckStatus())
                    || ActStatus.ACT_STATUS_AUDIT_PASS.getCode().equals(dbMemberAct.getCheckStatus())
                    || ActStatus.ACT_STATUS_PAID.getCode().equals(dbMemberAct.getCheckStatus())) {
                //查找众筹项目
                TargetProject targetProject = targetProjectService.findByOrderId(dbMemberAct.getOrderId());
                Project project = projectService.get(targetProject.getProjectId());
                map.put("id", project.getId());
                return map;
            }

            this.updateOrder(applyInput, activity.getPrice(), dbMemberAct.getOrderId());
            memberAct = this.updateMemberAct(applyInput, activity.getPrice(), dbMemberAct);
        }
        //新增报名
        else {
            String orderId = this.saveOrder(applyInput, memberId, counterfoil);
            memberAct = this.saveMemberAct(applyInput, memberId, orderId, counterfoil);
            logger.info("当前新增报名信息：" + memberAct.toString());
        }

        //调用生成众筹
        String id = projectBizService.insert(memberAct, memberId, applyInput, payType, counterfoil);
        //维护多票据数据
        CounterfoilBusiness search = new CounterfoilBusiness();
        search.setBusinessId(id);
        search.setCounterfoilId(counterfoil.getId());
        search.setCreateBy(memberId);
        counterfoilBusinessService.insert(search);
        counterfoil.setJoinNum(counterfoil.getJoinNum() + 1);
        counterfoilService.update(counterfoil);

        map.put("orderId", memberAct.getOrderId());
        map.put("id", id);
        map.put("memberActId", memberAct.getId());
        return map;
    }


    /**
     * 报名分销关系（短信发送）
     *
     * @param applyInput 输入实体
     * @param memberAct  报名信息
     * @param id         众筹编号
     */
    public void applyDistributor(ApplyInput applyInput, MemberAct memberAct,
                                 String id, DistributorRelation distributorRelation) {

        //如果存在分销关系
        if (null != distributorRelation) {
            StatisticsInput statisticsInput = new StatisticsInput();
            statisticsInput.setApplyId(memberAct.getId());
            statisticsInput.setOrderId(memberAct.getOrderId());
            statisticsInput.setProjectId(id);
            statisticsInput.setDistributorId(applyInput.getDistributorId());
            statisticsInput.setDistributorParentId(applyInput.getDistributorParentId());
            statisticsInput.setDistributorTargetId(applyInput.getDistributorTargetId());
            statisticsInput.setDistributionType(applyInput.getDistributionType());
            this.statistics(statisticsInput);
        } else {
            //来源于哪个众筹
            if (!Strings.isNullOrEmpty(applyInput.getSourceProjectId())) {
                Project project = projectService.get(applyInput.getSourceProjectId());
                DistributorDetail distributorDetail = distributorDetailService.findByTargetId(project.getId());
                if (null != distributorDetail) {
                    //生成众筹详情
                    this.statistics(distributorDetail.getDistributorRelationId(), memberAct.getId(), memberAct.getOrderId(), id);
                }
            }
        }
    }


    /**
     * 发送众筹成功消息
     *
     * @param projectId     项目编号
     * @param memberId      会员编号
     * @param distributorId 联合发起人id
     */
    public void send(String projectId, String memberId, String distributorId, Integer distributionType) {
        Project project = projectService.get(projectId);
        Member member = memberService.get(memberId);

        //发送众筹成功消息
        notifySendService.sendLaunchProject(project, member);

        TargetProject targetProject = targetProjectService.findByProjectId(projectId);
        Activity activity = activityService.get(targetProject.getTargetId());

        try {
            // 合作商推送
            MemberGroup receiver = memberGroupService.get(activity.getMember());
            officialPartnerNotifySendService.sendCrowdfundApply(project, member, receiver);
        } catch (Exception e) {
            e.printStackTrace();
        }

        if (StringUtils.isNotEmpty(distributorId) && null != distributionType) {
            try {
                // 联合发起人推送
                Member partnerReceiver = memberService.get(distributorId);
                if (partnerReceiver != null) {
                    if (DistributorRelationType.CROWDFUND_REPRESENT.getCode().equals(distributionType)) {
                        copartnerNotifySendService.sendCrowdfundApply(project, member, partnerReceiver.getId(),
                                partnerReceiver.getMobile(), IdentityType.PARTNER.getCode());
                    } else if (DistributorRelationType.CROWDFUND_DISTRIBUTION.getCode().equals(distributionType)) {
                        copartnerNotifySendService.sendCrowdfundApply(project, member, partnerReceiver.getId(),
                                partnerReceiver.getMobile(), IdentityType.CHANNEL_DIS.getCode());
                    }
                }
            } catch (Exception e) {
                logger.error("发起众筹——联合发起人消息推送异常", e);
            }
        }

        if (StringUtils.isNotEmpty(activity.getCosponsorId())) {
            try {
                // 合作渠道推送
                MemberGroup receiver = memberGroupService.get(activity.getCosponsorId());
                if (receiver != null) {
                    copartnerNotifySendService.sendCrowdfundApply(project, member, receiver.getId(), receiver.getMobile(),
                            IdentityType.COSPONSOR.getCode());
                }
            } catch (Exception e) {
                logger.error("发起众筹——合作渠道消息推送异常", e);
            }
        }
    }


    /**
     * 更新订单
     *
     * @param applyInput 输入视图
     * @param price      价格
     * @param orderId    订单号
     */
    public void updateOrder(ApplyInput applyInput, float price, String orderId) {
        OrderForm orderForm = orderFormService.get(orderId);
        orderForm.setLinkman(applyInput.getRealname());// 联系人
        orderForm.setPhone(applyInput.getMobile());// 手机
        float payment = price * orderForm.getUnit(); // 金额
        orderForm.setPayment(payment);
        orderForm.setStatus(OrderStatus.ORDER_STATUS_TO_BE_PAID.getCode()); // 待支付
        orderForm.setMerchantId(TradeStatus.ZCXM.getCode()); // 设为ZCXM
        orderFormService.update(orderForm);// 更新订单信息
    }

    /**
     * 更新报名信息
     *
     * @param applyInput 输入视图
     * @param price      价格
     * @param memberAct  报名信息
     */
    public MemberAct updateMemberAct(ApplyInput applyInput, float price, MemberAct memberAct) {
        memberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_PASS.getCode()); // 待支付
        memberAct.setJoinin(YesNoStatus.YES.getCode());
        memberAct.setName(applyInput.getRealname()); // 联系人
        memberAct.setMobile(applyInput.getMobile()); // 手机
        memberAct.setCompany(applyInput.getCompany()); // 公司名称
        memberAct.setJobTitle(applyInput.getTitle()); // 公司职位
        memberAct.setPayment(price); // 活动费用
        memberActService.update(memberAct);// 更新报名信息
        return memberAct;
    }

    /**
     * 活动订单下单
     *
     * @param input    输入视图
     * @param memberId 会员编号
     * @return 订单编号
     */
    public String saveOrder(ApplyInput input, String memberId, Counterfoil counterfoil) {
        BookOrderInput bookOrderInput = new BookOrderInput();
        bookOrderInput.setType(OrderType.ORDER_ACTIVITY.getCode());
        bookOrderInput.setStatus(OrderStatus.ORDER_STATUS_TO_BE_PAID.getCode());

        bookOrderInput.setGoodsId(input.getId());
        bookOrderInput.setUnit(1);
        bookOrderInput.setLinkman(input.getRealname());
        bookOrderInput.setPhone(input.getMobile());
        bookOrderInput.setMerchantId(TradeStatus.ZCXM.getCode());
        OrderOutput orderOutput = this.bookActOrder(bookOrderInput, memberId, counterfoil);
        return orderOutput.getId();
    }


    /**
     * 订单预定
     *
     * @param input    输入视图
     * @param memberId 会员主键
     * @return 订单信息
     */
    @Transactional
    public OrderOutput bookActOrder(BookOrderInput input, String memberId, Counterfoil counterfoil) throws BusinessException {
        OrderForm orderForm = new OrderForm();
        orderForm.setMemberId(memberId);
        Activity activity = activityService.get(input.getGoodsId());
        if (null == activity) {
            throw new BusinessException(PartyCode.ACTIVITY_UNEXIST, "活动不存在");
        }
        if (StringUtils.isNotEmpty(input.getMerchantId())) {
            orderForm.setMerchantId(input.getMerchantId());
        }
        orderForm.setGoodsId(input.getGoodsId());
        orderForm.setUnit(input.getUnit());
        orderForm.setLinkman(input.getLinkman());
        orderForm.setPhone(input.getPhone());
        orderForm.setType(input.getType());
        orderForm.setStatus(input.getStatus());
        orderForm.setIsPay(PaymentState.NO_PAY.getCode());
        //如果是分享商品 统计
        if (!Strings.isNullOrEmpty(input.getStoreGoodsId())) {
            orderForm.setStoreGoodsId(input.getStoreGoodsId());
        }

        if (input.getPayment() == null) {
            input.setPayment(counterfoil.getPayment());
        }

        double payment = BigDecimalUtils.mul(input.getPayment(), input.getUnit());
        double payment2 = BigDecimalUtils.round(payment, 2);
        orderForm.setPayment((float) payment2);
        orderForm.setTitle(activity.getTitle());
        orderForm.setInitiatorId(activity.getMember());
        orderFormService.insert(orderForm);

        try {
            Member member = memberService.get(orderForm.getMemberId());
            MemberGroup initiator = memberGroupService.get(orderForm.getInitiatorId());

            OrderFormSubInfo formSubInfo = new OrderFormSubInfo();
            formSubInfo.setOrderId(orderForm.getId());
            if (null != member) {
                formSubInfo.setAuthorLogo(member.getLogo());
                formSubInfo.setAuthorName(member.getRealname());
            }
            if (null != initiator) {
                formSubInfo.setInitiatorLogo(initiator.getLogo());
                formSubInfo.setInitiatorName(initiator.getRealname());
            }
            orderFormSubInfoService.insert(formSubInfo);
        } catch (Exception e) {
            logger.error("保存订单附属信息异常", e);
        }

        //输出视图
        OrderOutput orderOutput = OrderOutput.transform(orderForm);
        orderOutput.setDescription(activity.getTitle());
        orderOutput.setLogo(activity.getPic());


        //判断是否是多场活动
        if (StringUtils.isEmpty(activity.getEventId())) {
            orderOutput.setStartTime(activity.getStartTime());
            orderOutput.setEndTime(activity.getEndTime());
        }


        return orderOutput;
    }



    /**
     * 保存报名信息
     *
     * @param input
     * @param memberId
     * @return
     */
    public MemberAct saveMemberAct(ApplyInput input, String memberId, String orderId, Counterfoil counterfoil) {
        MemberAct memberAct = new MemberAct();
        memberAct.setActId(input.getId());
        memberAct.setMemberId(memberId);
        memberAct.setName(input.getRealname());
        memberAct.setMobile(input.getMobile());
        memberAct.setCompany(input.getCompany());
        memberAct.setJobTitle(input.getTitle());

        Activity activity = activityService.get(input.getId());

        //报名验证
        this.verifyApply(activity);

        memberAct.setPayment(counterfoil.getPayment());
        memberAct.setUpdateBy(memberId);
        memberAct.setJoinin(YesNoStatus.YES.getCode());//报名
        memberAct.setCollect(YesNoStatus.YES.getCode());
        memberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_PASS.getCode());
        //将订单Id放入报名表
        memberAct.setOrderId(orderId);
        BaseModel.preByInfo(memberId, memberAct);
        memberActService.insert(memberAct);

        try {
            //机构用户
            PartnerMember partnerMember = new PartnerMember();
            partnerMember.setPartnerId(activity.getMember());
            partnerMember.setMemberId(memberId);
            partnerMemberService.getSet(partnerMember);
        } catch (Exception e) {
            logger.error("众筹报名保存用户和机构的关系异常：orgId:{},memberId:{}", e, activity.getMember(), memberId);
        }
        // 个人统计表添加数据
//        memberPersonalCountBizService.getSet(activity.getMember(), memberId);
        return memberAct;
    }


    /**
     * 活动报名验证
     *
     * @param activity 活动信息
     * @return 数据异常
     */
    public void verifyApply(Activity activity) {

        //验证报名结束时间
        boolean isVerifyDate = DateUtils.afterTodayDate(activity.getEndTime());
        if (!isVerifyDate) {
            throw new BusinessException(PartyCode.JOIN_ACT_ENDDATE_ERROR, "报名失败，报名时间晚于报名结束时间");
        }

//        //验证人数上限
//        Integer applyNum = memberActService.findMemberNum(activity.getId()).size();
//        if (applyNum >= activity.getLimitNum()) {
//            throw new BusinessException(PartyCode.JOIN_ACT_LIMITNUM_ERROR, "报名失败，报名人数上限已满");
//        }
    }

    /**
     * 活动报名验证__多场
     *
     * @param activity 活动信息
     * @return 数据异常
     */
    public void gradationVerifyApply(Activity activity) {
        //最后阶段主题
        EventGradation ongoingGradation = eventGradationService.getTheLastGradation(activity.getEventId());

        //验证报名结束时间
        boolean isVerifyDate = DateUtils.afterTodayDate(ongoingGradation.getEndTime());
        if (!isVerifyDate) {
            throw new BusinessException(PartyCode.JOIN_ACT_ENDDATE_ERROR, "报名失败，报名时间晚于报名结束时间");
        }
        //验证人数上限
        Integer applyNum = memberActService.findMemberNum(activity.getId()).size();
        if (applyNum >= activity.getLimitNum()) {
            throw new BusinessException(PartyCode.JOIN_ACT_LIMITNUM_ERROR, "报名失败，报名人数上限已满");
        }
    }


    /**
     * 统计发起众筹详情
     *
     * @param input 输入视图
     */
    public void statistics(StatisticsInput input) {

        ApplyDistributorInput applyDistributorInput = new ApplyDistributorInput();
        applyDistributorInput.setDistributorId(input.getDistributorId());
        applyDistributorInput.setDistributorParentId(input.getDistributorParentId());
        applyDistributorInput.setDistributorType(input.getDistributionType());
        applyDistributorInput.setDistributorTargetId(input.getDistributorTargetId());

        //统计报名
        applyDistributorInput.setTargetId(input.getApplyId());
        applyDistributorInput.setType(DistributorDetailType.DISTRIBUTOR_TYPE_APPLY.getCode());
        distributorBizService.setDistributorData(applyDistributorInput);

        //统计订单
        applyDistributorInput.setTargetId(input.getOrderId());
        applyDistributorInput.setType(DistributorDetailType.DISTRIBUTOR_TYPE_ORDER.getCode());
        distributorBizService.setDistributorData(applyDistributorInput);

        //统计众筹
        applyDistributorInput.setTargetId(input.getProjectId());
        applyDistributorInput.setType(DistributorDetailType.DISTRIBUTOR_TYPE_CROWDFUN.getCode());
        distributorBizService.setDistributorData(applyDistributorInput);
    }

    /**
     * 统计发起众筹详情
     *
     * @param distributorRelationId 分销关系编号
     * @param applyId               报名编号
     * @param orderId               订单编号
     * @param projectId             众筹编号
     */
    public void statistics(String distributorRelationId, String applyId, String orderId, String projectId) {
        //统计报名
        distributorBizService.setDistributorData(distributorRelationId, applyId, DistributorDetailType.DISTRIBUTOR_TYPE_APPLY.getCode());

        //统计订单
        distributorBizService.setDistributorData(distributorRelationId, orderId, DistributorDetailType.DISTRIBUTOR_TYPE_ORDER.getCode());

        //统计众筹
        distributorBizService.setDistributorData(distributorRelationId, projectId, DistributorDetailType.DISTRIBUTOR_TYPE_CROWDFUN.getCode());
    }


    /**
     * 人员列表数据
     *
     * @param targetId 目标编号
     * @return 数据
     */
    public TabDataOutput tabData(String targetId) {
        Activity activity = activityService.get(targetId);
        if (null == activity) {
            throw new BusinessException("众筹项目不存在");
        }
        Integer crowdfundNum = projectService.directPaySizeForTargetId(targetId, null, null);
        TabDataOutput tabDataOutput = new TabDataOutput(crowdfundNum, activity.getRepresentNum());
        tabDataOutput.setCrowdFundedNum(activity.getCrowdfundedNum());
        return tabDataOutput;
    }

    public TabDataOutput newTabData(String targetId, String relationId) {
        Integer crowdfundNum = projectService.sizeForTargetId(targetId, relationId, null);
        Integer crowdfundedNum = projectService.sizeForTargetId(targetId, relationId, YesNoStatus.YES.getCode());
        TabDataOutput tabDataOutput = new TabDataOutput();
        tabDataOutput.setCrowdfundNum(crowdfundNum);
        tabDataOutput.setCrowdFundedNum(crowdfundedNum);
        return tabDataOutput;
    }

    /**
     * 处理报名后续
     *
     * @param applyInput 输入参数
     * @param memberId   用户id
     * @param projectId  众筹id
     * @param payType    支付方式
     */
    public void dealCrowdApply(ApplyInput applyInput, String memberId, String projectId, Integer payType) {
        Activity activity = activityService.get(applyInput.getId());
        CrowdfundEvent crowdfundEvent = crowdfundEventService.get(activity.getEventId());


        MemberAct memberAct = memberActService.findByMemberAct(memberId, applyInput.getId());

        if (null == applyInput.getDistributionType()) {
            applyInput.setDistributionType(DistributorRelationType.CROWDFUND_REPRESENT.getCode());
        }

        //分销统计
        DistributorRelation distributorRelation
                = distributorRelationService.get(applyInput.getDistributionType(),
                applyInput.getDistributorTargetId(), applyInput.getDistributorId());

        new Thread(() -> {
            //异步处理分销数据，有悲观锁
            applyDistributor(applyInput, memberAct, projectId, distributorRelation);
        }).start();


        String actId = applyInput.getId();
        new Thread(() -> {
            Activity actObj = activityService.rowLockQueryActivity(actId);
            if (null != actObj) {
                actObj.setBeCrowdfundNum(actObj.getBeCrowdfundNum() + 1);
                actObj.setJoinNum(actObj.getJoinNum() + 1);
                activityService.update(actObj);
            }
        }).start();

        try {
            memberPersonalCountBizService.updateCrowdfundNum(activity.getMember(), memberId, true);
        } catch (Exception e) {
            logger.error("实时更新个人统计数据众筹数量失败", e);
        }

        try {
            memberCopartnerDetailBizService.updateApplyNum(projectId);
        } catch (Exception e) {
            logger.error("实时更新合伙人报名统计数异常", e);
        }

        String distributorId = null == distributorRelation ? null : distributorRelation.getDistributorId();
        Integer distributionType = null == distributorRelation ? null : distributorRelation.getType();
        try {
            if(YesNoStatus.YES.getCode() == crowdfundEvent.getIsMultiple()){  // 是否为多场 0：单场 1：多场
                EventGradation gradation = eventGradationService.findOngoingGradation(crowdfundEvent.getId());

                projectMessageService.gradationApplySend(projectId, memberId, distributorId, distributionType,gradation);
            }else{
                send(projectId, memberId, distributorId, distributionType);
            }
        } catch (Exception e) {
            logger.error("消息推送异常", e);
        }

        try {
            memberMerchantDetailBizService.updateApplyNum(activity.getMember());
        } catch (Exception e) {
            logger.error("实时更新机构报名统计数异常", e);
        }

        try {
            projectDetailCountBizService.getSet(projectId, new Date());
        } catch (Exception e) {
            logger.error("众筹报名统计分析插入异常", e);
        }

        try {
            String filePath;
            String content;
            if (payType != null && payType == Constant.IS_DIRECTPAY_CROWDFUNDED) {
                filePath = fileBizService.getUploadCIPath("directPay", memberId);
                content = "project/direct_detail.html?id=" + projectId;//直接付款众筹
            } else if (YesNoStatus.YES.getCode() == crowdfundEvent.getIsMultiple()) {
                // 是否为多场 0：单场 1：多场
                filePath = fileBizService.getUploadCIPath("crowdfund", memberId);
                content = "project/project_multi_detail.html?id=" + projectId; //阶段众筹
            } else {
                filePath = fileBizService.getUploadCIPath("crowdfund", memberId);
                content = "project/project_detail.html?id=" + projectId;//普通众筹
            }
            String previewPicUrl = fileBizService.uploadCloudOut(projectId, filePath, content, activity.getMember());
            if (previewPicUrl == null) {
                if (payType != null && payType == Constant.IS_DIRECTPAY_CROWDFUNDED) {
                    logger.error("生成直接付款众筹详情二维码异常——众筹项目id= " + activity.getId() + "——众筹id=" + projectId);
                } else {
                    logger.error("生成众筹详情二维码异常——众筹项目id= " + activity.getId() + "——众筹id=" + projectId);
                }
            }
        } catch (Exception e) {
            if (payType != null && payType == Constant.IS_DIRECTPAY_CROWDFUNDED) {
                logger.error("生成直接付款众筹详情二维码异常", e);
            } else {
                logger.error("生成众筹详情二维码异常", e);
            }
        }
    }


    /**
     * 活动报名__多场
     *
     * @param applyInput 输入视图
     * @param memberId   会员编号
     * @param payType    付款类型
     * @return 报名信息
     */
    @Transactional
    public Map<String, Object> gradationApply(ApplyInput applyInput, String memberId, Integer payType) {
        Map<String, Object> map = Maps.newHashMap();
        MemberAct dbMemberAct = memberActService.findByMemberAct(memberId, applyInput.getId());
        Activity activity = activityService.get(applyInput.getId()); // 对应活动
        MemberAct memberAct = new MemberAct();

        if (sysConfigService.isOpenExpirationRestriction()) {
            boolean isExpire = MemberFormUtil.isExpire(activity.getMember(), null);
            if (isExpire) {
                throw new BusinessException("该商户歇业中，无法报名");
            }
        }
        map.put("isApply",false);
        //修改报名
        if (null != dbMemberAct) {
            map.put("isApply",true);
            // 已经报名,取出报名信息
            logger.info("已经存在报名信息：" + dbMemberAct.toString());
            if (ActStatus.ACT_STATUS_AUDITING.getCode().equals(dbMemberAct.getCheckStatus())
                    || ActStatus.ACT_STATUS_AUDIT_PASS.getCode().equals(dbMemberAct.getCheckStatus())
                    || ActStatus.ACT_STATUS_PAID.getCode().equals(dbMemberAct.getCheckStatus())) {
                //查找众筹项目
                TargetProject targetProject = targetProjectService.findByOrderId(dbMemberAct.getOrderId());
                Project project = projectService.get(targetProject.getProjectId());
                map.put("id", project.getId());
                return map;
            }
            this.updateOrder(applyInput, activity.getPrice(),dbMemberAct.getOrderId());
            memberAct = this.updateMemberAct(applyInput,activity.getPrice(),dbMemberAct);
        }

        //新增报名
        if(null==dbMemberAct) {
            String orderId = this.gradationSaveOrder(applyInput, activity.getPrice(), memberId);
            memberAct = this.gradationSaveMemberAct(applyInput, memberId, orderId,activity.getPrice());
            logger.info("当前新增报名信息：" + memberAct.toString());
        }

        //调用生成众筹
        String id = projectBizService.insert(memberAct, memberId, applyInput, payType, null);


        //保存众筹多场附属表
        EventGradation eventGradation = new EventGradation();
        eventGradation.setEventId(activity.getEventId());
        List<EventGradation> eventGradationList =
                eventGradationService.getGradationList(eventGradation,1);  //sign（0：众筹结束阶段/1：报名阶段和未开始的阶段）

        ProjectGradation pg  = null;
        Date endTime_last = null;// 众筹截止时间--最后一个

        for (int i = 0; eventGradationList.size() > i; i++) {
            pg = new ProjectGradation();
            pg.setEventGradationId(eventGradationList.get(i).getId());
            pg.setProjectId(id);
            pg.setSuccessTime(DateUtils.getDateFirstYear(DateUtils.DATETIME_PATTERN));//默认为1970-01-01 00:00:00
            pg.setTargetAmount(eventGradationList.get(i).getPrice());
            projectGradationService.insert(pg);
            if (i == 0) {
                ProjectInfoGradation pig = new ProjectInfoGradation();
                pig.setProjectGradationId(pg.getId());
                pig.setProjectId(id);
                pig.setChallengeState(ProjectInfoGradation.CHALLENGESTATE_RUN);
                projectInfoGradationService.insert(pig);
            }
            endTime_last = eventGradationList.get(i).getEndTime();
        }

        Project project_gra = projectService.get(id);
        project_gra.setEndDate(endTime_last);
        projectService.update(project_gra);

        map.put("orderId", memberAct.getOrderId());
        map.put("id", id);
        map.put("memberActId", memberAct.getId());
        return map;
    }

    /**
     * 获取活动详情__多场
     *
     * @param id          编号
     * @param currentUser 当前用户
     * @return 活动详情D
     */
    public ActivityDetailOutput gradationDetail(String id, CurrentUser currentUser, Integer type) {
        Activity activity = activityService.get(id);
        if (null == activity || activity.getDelFlag().equals("1")) {
            throw new BusinessException(PartyCode.IS_NO_DATA, "该众筹项目不存在");
        }
        ActivityDetailOutput activityDetailOutput = ActivityDetailOutput.transform(activity);

        int joinNum = orderFormService.calculateBuyNum(activity.getId(), null, false, OrderType.ORDER_ACTIVITY.getCode());

        // 报名人数带退款
        Integer crowdfundNum = projectService.countByActivity(activity.getId(), null);
        activityDetailOutput.setJoinNum(crowdfundNum);
        activityDetailOutput.setProjectJoinNum(joinNum);

        //是否已经到期
        Integer result = DateUtils.compareDate(new Date(), activity.getEndTime());
        if (result == 1) {
            activityDetailOutput.setClosed(true);
        }

        //创建者
        MemberGroup member = memberGroupService.get(activity.getMember());
        if (!Strings.isNullOrEmpty(activity.getPublisher()) && !Strings.isNullOrEmpty(activity.getPublisher())) {
            activityDetailOutput.setAuthorName(activity.getPublisher());
            activityDetailOutput.setAuthorLogo(activity.getPublisherLogo());
        } else {
            activityDetailOutput.setAuthorName(member.getRealname());
            activityDetailOutput.setAuthorLogo(member.getLogo());
        }
        activityDetailOutput.setAuthorId(activity.getMember());
        activityDetailOutput.setTemplateStyle(activity.getTemplateStyle());

        //详情
        ActivityDetail activityDetail = activityDetailService.getByRefId(activity.getId());
        if (null != activityDetail) {
            activityDetailOutput.setContent(StringEscapeUtils.unescapeHtml4(activityDetail.getContent()));
            activityDetailOutput.setMatchStandard(StringEscapeUtils.unescapeHtml4(activityDetail.getMatchStandard()));
            activityDetailOutput.setApplyRelated(StringEscapeUtils.unescapeHtml4(activityDetail.getApplyRelated()));
        }

        // 跑马灯
        List<CrowfundResources> picList = crowfundResourcesService.findByRefId(activity.getId(), "1");
        activityDetailOutput.setPicList(picList);

        // 视频
        List<CrowfundResources> videoList = crowfundResourcesService.findByRefId(activity.getId(), "2");
        if (videoList.size() > 0) {
            activityDetailOutput.setVideo(videoList.get(0));
        }

        if (null != currentUser) {
            //是否报名过
            MemberAct memberAct = memberActService.findByMemberAct(currentUser.getId(), id);
            if (memberAct != null) {
                TargetProject targetProject = targetProjectService.findByOrderId(memberAct.getOrderId());
                Project project = projectService.get(targetProject.getProjectId());
                activityDetailOutput.setMyProjectId(project.getId());
            }

            if (null == type) {
                type = DistributorRelationType.CROWDFUND_REPRESENT.getCode();
            }

            //是否已经众筹
            DistributorRelation distributorRelation
                    = distributorRelationService.get(type, id, currentUser.getId());
            if (null != distributorRelation) {
                activityDetailOutput.setParentId(distributorRelation.getParentId());
                activityDetailOutput.setDistributorId(distributorRelation.getDistributorId());
            }
        } else {
            logger.error("没有获取到登录用户；项目id--{}", id);
        }

        //如果没有绑定事件
        if (!Strings.isNullOrEmpty(activity.getEventId())) {
            Activity count = activityService.countForEventId(activity.getEventId());

            //报名人数带退款
            Integer allJoinNum = projectService.countByEvent(activity.getEventId(), null);
            activityDetailOutput.setJoinNum(allJoinNum);
            activityDetailOutput.setFavorerNum(count.getFavorerNum());
            activityDetailOutput.setBeCrowdfundNum(count.getBeCrowdfundNum());
            activityDetailOutput.setCrowdfundedNum(count.getCrowdfundedNum());
        }

        MemberGroup newPartner = memberGroupService.getPartner(activity.getMember());
        //公众号信息
        //MemberMerchant memberMerchant = memberMerchantService.findByMemberId(activity.getMember());
        if (newPartner != null && newPartner.getOpenStatus().equals(YesNoStatus.YES.getCode())) {
            if (YesNoStatus.YES.getCode().equals(newPartner.getMandatoryAttention())) {
                MemberExternalApp memberExternalApp
                        = memberExternalAppService.findByMemberIdAndDeployType(newPartner.getId(),
                        newPartner.getDeployType());
                WechatOpenMember wechatOpenMember = wechatOpenMemberService.get(memberExternalApp.getExternalAccountId());
                activityDetailOutput.setQrUrl(wechatOpenMember.getQrcodeUrl());
                activityDetailOutput.setHeadImg(wechatOpenMember.getHeadImg());
                activityDetailOutput.setAppName(wechatOpenMember.getNickName());
            }
        } else {
            activityDetailOutput.setQrUrl(qrUrl);
            activityDetailOutput.setHeadImg(headImgUrl);
            activityDetailOutput.setAppName(appName);
        }

        //是否播放音乐(0否/是)
        Integer isPlayMusic = 0;
        //音频url
        String audioUrl = "";
        try {
            Audio audio = audioService.findAudioByEventId(activity.getEventId());
            if (null != audio) {
                isPlayMusic = 1;
                audioUrl = audio.getAudioUrl();
            }
        } catch (Exception e) {
            logger.info("众筹项目详情页H5,音频获取失败", e.getMessage());
        }
        activityDetailOutput.setIsPlayMusic(isPlayMusic);
        activityDetailOutput.setAudioUrl(audioUrl);


        //多阶段众筹__获取正在进行主题的阶段金额,结束时间
        double price_gradation = 0d;
        Date endTime_gradation = null;
        try {
            EventGradation ongoingGradation = eventGradationService.findOngoingGradation(activity.getEventId());
            if(null==ongoingGradation){
                //最后阶段主题
                ongoingGradation = eventGradationService.getTheLastGradation(activity.getEventId());
            }
            price_gradation = ongoingGradation.getPrice();
            endTime_gradation = ongoingGradation.getEndTime();
        } catch (Exception e) {
            logger.info("多阶段众筹__获取正在进行主题的结束时间,获取失败", e.getMessage());
        }

        activityDetailOutput.setPrice((float) price_gradation);
        activityDetailOutput.setEndTime(endTime_gradation);
        //activityDetailOutput.setLimitNum(limitNUm);
        return activityDetailOutput;
    }

    /**
     * 更新订单__多场
     *
     * @param applyInput 输入视图
     * @param orderId    订单号
     */
    public void gradationUpdateOrder(ApplyInput applyInput, String orderId) {
        OrderForm orderForm = orderFormService.get(orderId);
        orderForm.setLinkman(applyInput.getRealname());// 联系人
        orderForm.setPhone(applyInput.getMobile());// 手机
        float payment = orderForm.getPayment() * orderForm.getUnit(); // 金额
        orderForm.setPayment(payment);
        orderForm.setStatus(OrderStatus.ORDER_STATUS_TO_BE_PAID.getCode()); // 待支付
        orderForm.setMerchantId(TradeStatus.ZCXM.getCode()); // 设为ZCXM
        orderFormService.update(orderForm);// 更新订单信息
    }


    /**
     * 更新报名信息___多场
     *
     * @param applyInput 输入视图
     * @param memberAct  报名信息
     */
    public MemberAct gradationUpdateMemberAct(ApplyInput applyInput, MemberAct memberAct) {
        memberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_PASS.getCode()); // 待支付
        memberAct.setJoinin(YesNoStatus.YES.getCode());
        memberAct.setName(applyInput.getRealname()); // 联系人
        memberAct.setMobile(applyInput.getMobile()); // 手机
        memberAct.setCompany(applyInput.getCompany()); // 公司名称
        memberAct.setJobTitle(applyInput.getTitle()); // 公司职位
        memberActService.update(memberAct);// 更新报名信息
        return memberAct;
    }


    /**
     * 活动订单下单___多场
     *
     * @param input    输入视图
     * @param price    价格
     * @param memberId 会员编号
     * @return 订单编号
     */
    public String gradationSaveOrder(ApplyInput input, float price, String memberId) {
        BookOrderInput bookOrderInput = new BookOrderInput();
        bookOrderInput.setType(OrderType.ORDER_ACTIVITY.getCode());
        bookOrderInput.setStatus(OrderStatus.ORDER_STATUS_TO_BE_PAID.getCode());

        bookOrderInput.setGoodsId(input.getId());
        bookOrderInput.setUnit(1);
        bookOrderInput.setLinkman(input.getRealname());
        bookOrderInput.setPayment(price);
        bookOrderInput.setPhone(input.getMobile());
        bookOrderInput.setMerchantId(TradeStatus.ZCXM.getCode());
        OrderOutput orderOutput = orderBizService.bookActOrder(bookOrderInput, memberId);
        return orderOutput.getId();
    }

    /**
     * 保存报名信息__多场
     *
     * @param input
     * @param memberId
     * @return
     */
    public MemberAct gradationSaveMemberAct(ApplyInput input, String memberId, String orderId, float price) {
        MemberAct memberAct = new MemberAct();
        memberAct.setActId(input.getId());
        memberAct.setMemberId(memberId);
        memberAct.setName(input.getRealname());
        memberAct.setMobile(input.getMobile());
        memberAct.setCompany(input.getCompany());
        memberAct.setJobTitle(input.getTitle());

        Activity activity = activityService.get(input.getId());

        //报名验证
        this.gradationVerifyApply(activity);

        memberAct.setPayment(price);
        memberAct.setUpdateBy(memberId);
        memberAct.setJoinin(YesNoStatus.YES.getCode());//报名
        memberAct.setCollect(YesNoStatus.YES.getCode());
        memberAct.setCheckStatus(ActStatus.ACT_STATUS_AUDIT_PASS.getCode());
        //将订单Id放入报名表
        memberAct.setOrderId(orderId);
        BaseModel.preByInfo(memberId, memberAct);
        memberActService.insert(memberAct);

        try {
            //机构用户
            PartnerMember partnerMember = new PartnerMember();
            partnerMember.setPartnerId(activity.getMember());
            partnerMember.setMemberId(memberId);
            partnerMemberService.getSet(partnerMember);
        } catch (Exception e) {
            logger.error("众筹报名保存用户和机构的关系异常：orgId:{},memberId:{}", e, activity.getMember(), memberId);
        }
        // 个人统计表添加数据
//        memberPersonalCountBizService.getSet(activity.getMember(), memberId);
        return memberAct;
    }
}
